/*
 * RouteSettings.cpp
 *
 *  Created on: Feb 20, 2011
 *      Author: kmueller
 */

#include "RoutingService.h"

#include "../gui/RouteWidget.h"
#include "../gui/SearchWidget.h"
#include "../gui/SettingsWidget.h"

#include "Main.h"
#include "Exceptions.h"
#include "Helpers.h"
#include "PositioningSystem.h"

#include <QtCore>

RouteSettings::RouteSettings(QObject* parent) :
	QObject(parent) {
	reset();
}

void RouteSettings::reset() {
	QtMobility::QGeoCoordinate
			org =
					Main::getInstance().getPositioningSystem().getLastPosition().coordinate();
	QtMobility::QGeoCoordinate dst;

	origin.setLabel(tr("Current GPS position"));
	origin.setCoordinate(org);

	destination.setLabel("");
	destination.setCoordinate(dst);

	Settings& s = Main::getInstance().getSettings();
	setPreferredRoute(s.getRouteCalculation()->getCurrent());
	avoidHighways(s.getAvoidHighways()->getCurrent() ? Qt::Checked
			: Qt::Unchecked);
	avoidTollroads(s.getAvoidTollroads()->getCurrent() ? Qt::Checked
			: Qt::Unchecked);
}

void RouteSettings::setOrigin(const LabeledCoordinate &c) {
	origin = c;
}

LabeledCoordinate RouteSettings::getOrigin() const {
	return origin;
}

void RouteSettings::setDestination(const LabeledCoordinate &c) {
	destination = c;
}

LabeledCoordinate RouteSettings::getDestination() const {
	return destination;
}

void RouteSettings::setPreferredRoute(int val) {
	preferredRoute = val;
}

int RouteSettings::getPreferredRoute() const {
	return preferredRoute;
}

void RouteSettings::avoidHighways(int val) {
	avoidHighways(val != Qt::Unchecked);
}

void RouteSettings::avoidHighways(bool val) {
	avoidHighways_ = val;
}

bool RouteSettings::isAvoidHighways() const {
	return avoidHighways_;
}

void RouteSettings::avoidTollroads(int val) {
	avoidTollroads(val != Qt::Unchecked);
}

void RouteSettings::avoidTollroads(bool val) {
	avoidToll_ = val;
}

bool RouteSettings::isAvoidTollroads() const {
	return avoidToll_;
}

RoutingService::RoutingService(opennav::Map* m){
	map = m;
	settings = Main::getInstance().getRouteSettings();
}

void RoutingService::setSettings(const RouteSettings* s) {
	settings = s;
}

int RoutingService::getRemainingTavelTime(const ExtendedGeoPositionInfo* gps){
	const opennav::Route* route = map->get_route();
	if(route==NULL){
		return -1;
	}
	mutex.lock();
	int travel = route->travel_time(gps!=NULL ? gps->getRoadSegment() : NULL, opennav::SECONDS);
	mutex.unlock();
	return travel;
}

int RoutingService::getRemainingDistance(const ExtendedGeoPositionInfo* gps){
	const opennav::Route* route = map->get_route();
	if(route==NULL){
		return -1;
	}
	mutex.lock();
	int length = route->length(gps!=NULL ? gps->getRoadSegment() : NULL);
	mutex.unlock();
	return length;
}

bool RoutingService::calculate() {
	if (mutex.tryLock()) {
		start();
		mutex.unlock();
		return true;
	}
	return false;
}

void RoutingService::stop(){
	map->delete_route();
	emit stopNavigation();
}

void RoutingService::run() {
	opennav::RoutingSettings setup(settings->getPreferredRoute()
			== RouteCalculation::SHORTEST ? opennav::RoutingSettings::SHORTEST
			: opennav::RoutingSettings::FASTEST, settings->isAvoidTollroads(),
			settings->isAvoidHighways());
	map->set_routing_settings(setup);

	opennav::Coordinate src(settings->getOrigin().longitude(),
			settings->getOrigin().latitude());
	opennav::Coordinate dst(settings->getDestination().longitude(),
			settings->getDestination().latitude());

	map->reset_route();
	if (map->calculate_route(src, dst)) {
		emit startNavigation();
	} else {
		emit noRoute();
	}
}
